import {DefineComponent, defineComponent, ref, defineExpose} from "vue";
import {
    FormRules,
    NForm,
    NFormItem,
    NGi,
    NGrid,
    NInput,
    NSelect,
    NDatePicker,
    NRadioGroup,
    NCheckboxGroup,
    NSpace,
    NRadio,
    NCheckbox,
    NSwitch,
    NCascader
} from "naive-ui"

type MySize = 'tiny' | 'small' | 'medium' | 'large' | undefined;
type Mypassword = "textarea" | "text" | "password" | undefined;

export interface flexformitem {
    slot?: string,
    show: boolean,   // 是否显示
    span: string,  //  宽度
    label: string, // 标题
    key: string, // 关键字
    default: string, // 默认值
    type: string, // 表单类型
    placeholder?: string,// 提示文字
    inputtype?: string, // input输入框的类型
    clearable?: boolean, // 清楚按钮
    disabled?: boolean,// 不可编辑
    size: MySize, // 大小
    change?: null | Function,  // 改变的回调
    options?: Array<any>, // 备选项
    required: string, // 是否必填
    maxlength?: string, // 最大长度
    multiple?: string,  // 是否多选
    tooltip?: string, // 滑块覆盖的提示
    placement?: string, // 提示的弹出位置
    max?: string, // 最大值
    min?: string, // 最小值
    datatype?: string, // 时间选择器的类型
    round?: string,  // 是否是圆形
    valueField?: string,   // 关键字
    labelField?: string, // 关键字
    childrenField?: string,  // 关键字
    filterable?: string,  // 过滤功能
    rules?: Array<any> | undefined,  // 校验规则
    path: string | undefined,   // 所在路径
    password: Mypassword,    // 是不是密码
    prefix: Function | undefined, //前缀
    suffix: Function | undefined,   //后缀
}

type MyFunction = (e: KeyboardEvent) => {}
// 回车按下的无效化
export const meiyongfunc = (event: KeyboardEvent) => {
    if (event.key === "Enter") {
        event.preventDefault()
    }
}


export default defineComponent({
    name: "flexform",
    props: {
        // 表单配置数组
        formList: {
            type: Array,
            default(data: Array<any>) {
                return data
            },
        },
        // 表单的值
        value: {
            type: Object,
            default(data: any) {
                return data || {}
            },
        },
        // 标题的宽度
        labelWidth: {
            type: Number,
            default: 100,
        },
        disabled: {
            type:Boolean,
            default:false,
        },
    },
    emits: ["update:value", "change"],
    setup({ labelWidth, value, formList,disabled,}, {emit,expose,}) {
        // 表单组件
        const formRef = ref<DefineComponent | null>(null)
        const rules = ref<FormRules>({})
        // 刷新回显e
        const shuaxin = (key: string | null = null, data: any) => {
            // console.log("要修改的key是：", key,data,{...value})
            if (key) {
                value[key] = data
            }
            // console.log({...value}, "现在的数据")
            // emit("update:value", {...value})
            emit("change",key,data)
        }
        // 校验函数
        const jiaoyan=(func:Function)=>{
            // console.log("出发校验1",)
            formRef.value?.validate((errors:any)=>{
                // console.log("出发校验2",)
                if(!errors){
                    // console.log("校验成功")
                    func()
                }else{
                    // console.log("校验失败")
                    return false
                }
            })
        }
        expose({jiaoyan})
        // 具体的输入组件
        const biaodanitem: { [key: string]: any } = {
            "slot": (item: any) => (item.slot ? item.slot(item,shuaxin) : null),
            "input": (item: any) => (
                <NFormItem label={item.label + "："} path={item.path || item.key} rule={item.rules || []}>
                    <NInput v-model={[value[item.key], "value"]} onKeydown={meiyongfunc}
                            type={item.password || "text"}
                            onUpdateValue={(val) => shuaxin(item.key, val)} placeholder={item.placeholder || "请输入"}
                            clearable={item.clearable} disabled={item.disabled}
                            size={item.size || "small"}>
                        {item.prefix ? item.prefix() : null}
                        {item.suffix ? item.suffix() : null}
                    </NInput>
                </NFormItem>),
            "textarea": (item: any) => (
                <NFormItem label={item.label + "："} path={item.path || item.key} rule={item.rules || []}>
                    <NInput v-model={[value[item.key], "value"]} onKeydown={meiyongfunc} type={"textarea"}
                            onUpdateValue={(val) => shuaxin(item.key, val)} placeholder={item.placeholder || "请输入"}
                            clearable={item.clearable} disabled={item.disabled}
                            size={item.size || "small"}>
                    </NInput>
                </NFormItem>),
            "select": (item: any) => (
                <NFormItem label={item.label + "："} path={item.path || item.key} rule={item.rules || []}>
                    <NSelect v-model={[value[item.key], "value"]}
                             onUpdateValue={(val) => shuaxin(item.key, val)} placeholder={item.placeholder || "请选择"}
                             clearable={item.clearable} disabled={item.disabled} options={item.options || []}
                             filterable={item.filterable} multiple={item.multiple} size={item.size || "small"}>
                    </NSelect>
                </NFormItem>),
            "picker": (item: any) => (
                <NFormItem label={item.label + "："} path={item.path || item.key} rule={item.rules || []}>
                    <NDatePicker v-model={[value[item.key], "value"]} type={item.dateType || "datetime"}
                                 onUpdateValue={(val) => shuaxin(item.key, val)} placeholder={item.placeholder || "请选择"}
                                 clearable={item.clearable} disabled={item.disabled} size={item.size || "small"}>
                    </NDatePicker>
                </NFormItem>),
            "radio": (item: any) => (
                <NFormItem label={item.label + "："} path={item.path || item.key} rule={item.rules || []}>
                    <NRadioGroup v-model={[value[item.key], "value"]}
                                 onUpdateValue={(val) => shuaxin(item.key, val)}
                                 disabled={item.disabled} size={item.size || "small"}>
                        <NSpace>
                            {() => item.options.map((option: any) => {
                                return <NRadio value={option.value}>{option.label}</NRadio>
                            })}
                        </NSpace>
                    </NRadioGroup>
                </NFormItem>),
            "checkbox": (item: any) => (
                <NFormItem label={item.label + "："} path={item.path || item.key} rule={item.rules || []}>
                    <NCheckboxGroup v-model={[value[item.key], "value"]}
                                    onUpdateValue={(val) => shuaxin(item.key, val)}
                                    disabled={item.disabled} size={item.size || "small"}>
                        <NSpace>
                            {item.options.map((option: any) => {
                                return () => (
                                    <NCheckbox value={option.value} label={option.label}/>
                                )
                            })}
                        </NSpace>
                    </NCheckboxGroup>
                </NFormItem>),
            "switch": (item: any) => (
                <NFormItem label={item.label + "："} path={item.path || item.key} rule={item.rules || []}>
                    <NSwitch v-model={[value[item.key], "value"]}
                             onUpdateValue={(val) => shuaxin(item.key, val)} round={item.round}
                             disabled={item.disabled} size={item.size || "small"}>
                    </NSwitch>
                </NFormItem>),
            "cascader": (item: any) => (
                <NFormItem label={item.label + "："} path={item.path || item.key} rule={item.rules || []}>
                    <NCascader v-model={[value[item.key], "value"]}
                               onUpdateValue={(val) => shuaxin(item.key, val)} placeholder={item.placeholder || "请选择"}
                               options={item.options || []} showPath={item.showPath} clearable={item.clearable}
                               valueField={item.valueField || "id"} labelField={item.labelField || "name"}
                               disabled={item.disabled} size={item.size || "small"}>
                    </NCascader>
                </NFormItem>),
        }
        return () => (
            <NForm ref={formRef} model={value} rules={rules.value}
                   label-width={labelWidth || 100}
                   label-placement="left" disabled={disabled}>
                <NGrid xGap={12}>
                    {formList.map((item: any) => {
                        return <NGi span={item.span || 24}>
                            {biaodanitem[item.type] && item.show !== false ? biaodanitem[item.type](item) : null}
                        </NGi>
                    })}
                </NGrid>
            </NForm>
        )
    },
})
